/*
 * Library.cpp
 *
 *  Created on: Jul 10, 2009
 *      Author: oferbart
 */

#include "Library.h"

// new process from the root
Library::Library(int id, SysCall* sysCall) {
	string _currPath = ""; // root
	_pid = id;
	_fdTable = new FileDescriptorTable();
	_commList = new UnboundedBlockingQueue();
	_sysCall = sysCall;
}

// new process created not from the root
Library::Library(int id, string currPath, SysCall* sysCall){
	string _currPath = currPath;
	_pid = id;
	_fdTable = new FileDescriptorTable();
	_commList = new UnboundedBlockingQueue();
	_sysCall = sysCall;
}

// new process with fork (same fd);
Library::Library(int id, Library father, SysCall* sysCall){
	_currPath = father._currPath;
	_pid = id;
	_fdTable = new FileDescriptorTable(*father._fdTable);
	_commList = new UnboundedBlockingQueue();
	_sysCall = sysCall;
}



Library::~Library() {
	// TODO Auto-generated destructor stub
}

/***********************************************************************
 * 		Process Function in the Library / UI
 ***********************************************************************/

int Library::processCommand(string command){

	//string command = _commList->removeElement();

	vector<string> tokens;
	Utils::tokenize(command,tokens," ");

	int size = tokens.size();

	if (tokens.at(0).compare("mkdir") == 0 && size == 2){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		int res = mkdir(tokens.at(1));
		return res;
	}
	if (tokens.at(0).compare("create") == 0 && size == 3){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		int res = create(tokens.at(1),tokens.at(2));
		if(res != -1){
			cout << "fd is: " << res << endl;
		}
		return res;
	}
	if (tokens.at(0).compare("hdlink") == 0 && size == 3){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		check = checkPathFileLength(tokens.at(2));
		if(check != 0){
			return -1;
		}
		int res = hdlink(tokens.at(1),tokens.at(2));
		return res;
	}
	if (tokens.at(0).compare("sflink") == 0 && size == 3){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		check = checkPathFileLength(tokens.at(2));
		if(check != 0){
			return -1;
		}
		int res = sflink(tokens.at(1),tokens.at(2));
		return res;
	}
	if (tokens.at(0).compare("open") == 0 && size == 3){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		int res = open(tokens.at(1),tokens.at(2));
		if(res != -1){
			cout << "fd is: " << res << endl;
		}
		return res;
	}
	if (tokens.at(0).compare("close") == 0 && size == 2){
		int fd = atoi(tokens.at(1).c_str());
		int res = close(fd);
		return res;
	}
	if (tokens.at(0).compare("read") == 0){
		int fd = atoi(tokens.at(1).c_str());
		//TODO make new string
		int numBytes = atoi(tokens.at(2).c_str());
		string res = read(fd, numBytes);
		if(res.length() != 0){
			cout << "Readed: " << (string)res;
			return 0;
		}
		// nothing to read
		return -1;
	}
	if (tokens.at(0).compare("write") == 0 && size >= 3){
		int fd = atoi(tokens.at(1).c_str());
		string text = Utils::vectorToText(&tokens);
		int res = write(fd,text);
		if(res != -1){
			cout << "Writed " << res << " bytes." << endl;
		}
		return res;
	}
	if (tokens.at(0).compare("writeFile") == 0 && size == 3){
		int fd = atoi(tokens.at(1).c_str());
		string realFileName = tokens.at(2);
		int res = writeFile(fd,realFileName);
		return res;
	}
	if (tokens.at(0).compare("lck_rd") == 0 && size == 2){
		int fd = atoi(tokens.at(1).c_str());
		int res = lck_rd(fd);
		return res;
	}
	if (tokens.at(0).compare("lck_wr") == 0 && size == 2){
		int fd = atoi(tokens.at(1).c_str());
		int res = lck_wr(fd);
		return res;
	}
	if (tokens.at(0).compare("rlslck_rd") == 0 && size == 2){
		int fd = atoi(tokens.at(1).c_str());
		int res = rlslck_rd(fd);
		return res;
	}
	if (tokens.at(0).compare("rlslck_wr") == 0 && size == 2){
		int fd = atoi(tokens.at(1).c_str());
		int res = rlslck_wr(fd);
		return res;
	}
	if (tokens.at(0).compare("lseek") == 0 && size == 3){
		int fd = atoi(tokens.at(1).c_str());
		int offset = atoi(tokens.at(2).c_str());
		int res = lseek(fd, offset);
		return res;
	}
	if (tokens.at(0).compare("rm") == 0 && size == 2){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		int res = rm(tokens.at(1));
		return res;
	}
	if (tokens.at(0).compare("rmdir") == 0 && size == 2){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		int res = rmdir(tokens.at(1));
		return res;
	}
	if (tokens.at(0).compare("rmdir_r") == 0 && size == 2){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		int res = rmdir_r(tokens.at(1));
		return res;
	}
	if (tokens.at(0).compare("ls") == 0 && size == 1){
		string res = ls("./");
		if(res.compare("") == 0){
			return -1;
		}
		cout << res;
		return 0;
	}
	if (tokens.at(0).compare("ls") == 0 && size == 2){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		string res = ls(tokens.at(1));
		if(res.compare("") == 0){
			return -1;
		}
		cout << res;
		return 0;
	}
	if (tokens.at(0).compare("mv") == 0 && size == 3){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		check = checkPathFileLength(tokens.at(2));
		if(check != 0){
			return -1;
		}
		int res = mv(tokens.at(1), tokens.at(2));
		return res;
	}
	if (tokens.at(0).compare("cd/")== 0 && size == 1){
		int check = checkPathFileLength("/.");
		if(check != 0){
			return -1;
		}
		cd("/.");
		return 0;
	}
	if (tokens.at(0).compare("cd..")== 0 && size == 1){
		int check = checkPathFileLength("..");
		if(check != 0){
			return -1;
		}
		cd("..");
		return 0;
	}
	if (tokens.at(0).compare("cd")== 0 && size == 2){
		int check = checkPathFileLength(tokens.at(1));
		if(check != 0){
			return -1;
		}
		cd(tokens.at(1));
		return 0;
	}
	if (tokens.at(0).compare("batch") == 0 && size == 2){
		int res = batch(tokens.at(1));
		return res;
	}
	cout << "~~~~ No Matching Command ~~~~" << endl;
	return -1;

}

int Library::checkPathFileLength(string path){

	vector<string>* v = Utils::tokPath(path.c_str());

	for(unsigned int i = 0; i < v->size(); i++){
		if(v->at(i).length() > 12){
			ostringstream str;
			str << "Name is to long, max length is 12: " << v->at(i) << endl;
			Log::log(str,0, "error");
			return -1;
		}
	}
	delete v;

	return 0;
}


int Library::batch(string batchfile){

	ifstream bFile;

	bFile.open(batchfile.c_str());
    if (!bFile) {
    	cout << errno << endl;
        cout << "Unable to open batch file: " << batchfile << endl;
        return -1; // terminate with error
    }

    string command = "";

	while(!bFile.eof()){
		command.clear();
		getline(bFile, command, '\n');
		//cout << "size: " << command.length() << endl;
		cout << " *** Batch-ProcessCommand: " << command << endl;

		if(command.length() != 0){
			//process command...
			int res = processCommand(command);
			cout << "Batch-result is: " << res << endl;
			cout << getCurrentPathName() << "::>";
		}
		/*
		if(res == -1){
			bFile.close();
			return res;
		}*/
    }
	bFile.close();
	return 0;
}


string Library::getFullPathName(string path){

	if (path.compare("") == 0){
		//root path
		return "/";
	}

	bool isfullPath = path.at(0) == '/';
	vector<string>* currPath = Utils::tokPath(_currPath);
	if(isfullPath){
		currPath->clear();
	}
	vector<string>* relPath = Utils::tokPath(path);


	for(unsigned int i = 0; i < relPath->size(); i++){
		if(relPath->at(i).compare("..") == 0){
			if(currPath->size() < 1){
				Log::log("Error: cannot go behind root directory\n",0,"error");
				return "";
			}
			currPath->pop_back();
			continue;
		}
		if(relPath->at(i).compare(".") == 0){
			continue;
		}
		currPath->push_back(relPath->at(i));
	}

	ostringstream fp;
	for(unsigned int i = 0; i < currPath->size(); i++){
		fp << "/" << currPath->at(i);
	}

	return fp.str();
}



int Library::getProcessID(){
	int ans = _pid;
	return ans;
}
string Library::getCurrentPathName(){
	string ans = _currPath;
	return ans;
}

void Library::setPathName(string path){
	_currPath = path;
}


void Library::sendMessage(string msg){
	_commList->addElement(msg);
}

void* Library::run(){

	while(1){
		//thread process run...path NO NEED
		//lalalala
	}

}


/***********************************************************************
 * 		Library Function / UI
 ***********************************************************************/


// makes a directory with the given name.
int Library::mkdir(string dir_name){
	string fullPath = getFullPathName(dir_name);
	char* path = (char*)fullPath.c_str();
	int res = _sysCall->MakeDir(path);
	//TODO what to do with res...
	return res;
}

// creates an empty file. Returns a file descriptor <fd>.
int Library::create(string file_name, string flags){
	if(_fdTable->isFull()){
		//cannot do that fd is full
		return -1;
	}
	string fullPath = getFullPathName(file_name);
	char* path = (char*)fullPath.c_str();
	int prem = getPremision(flags);
	if(prem == -1){
		// no such premision
		return -1;
	}
	int fd = _sysCall->MakeFile(path,prem);
	if(fd == -1){
		//makefile failed..
		return -1;
	}
	_fdTable->addFileDescriptor(fd);

	return fd;
}

// creates a hard link to file-to-link-to. Making a hard link to directories is not allowed.
int Library::hdlink(string file_to_link_to, string new_file_name){

	string fullPathLink = getFullPathName(file_to_link_to);
	char* pathLink = (char*)fullPathLink.c_str();

	string fullPathNew = getFullPathName(new_file_name);
	char* pathNew = (char*)fullPathNew.c_str();

	int ans = _sysCall->MakeHLink(pathLink, pathNew);

	if(ans == -1){
		// hd failed
	}

	return ans;
}

// creates a soft link to dest-to-link-to. dest can be either a directory or a file.
int Library::sflink(string dest_to_link_to, string new_file_name){

	string fullPathLink = getFullPathName(dest_to_link_to);
	char* pathLink = (char*)fullPathLink.c_str();

	ostringstream s1;
	s1 << "Library::sflink: dest_to_link_to: " << pathLink << "=!=" << endl;
	Log::log(s1.str(),0,"debug");

	string fullPathNew = getFullPathName(new_file_name);
	char* pathNew = (char*)fullPathNew.c_str();

	ostringstream s2;
	s2 << "Library::sflink: new_file_name: " << pathNew << "=!=" << endl;
	Log::log(s2.str(),0,"debug");

	int ans = _sysCall->MakeSoftLink(pathLink, pathNew, READWRITE);

	if(ans == -1){
		// sf failed
	}

	return ans;

}

// opens an existing file returning a file descriptor <fd>.
// The fd returned should always be the lowest one still free. Flag can be set to "read-only" or "read-and-write".
// Always remember to check when reading or writing that the file was actually opened for that purpose,
// otherwise return an error. Your flags should be in the exact syntax specified.
int Library::open(string file_name, string flags){
	if(_fdTable->isFull()){
		//cannot do that fd is full
		return -1;
	}
	string fullPath = getFullPathName(file_name);
	char* path = (char*)fullPath.c_str();
	int prem = getPremision(flags);
	if(prem == -1){
		// no such premision
		return -1;
	}
	int fd = _sysCall->Open(path, prem);
	if(fd == -1){
		//open failed..
		return -1;
	}
	_fdTable->addFileDescriptor(fd);

	return fd;
}

// close the file associated with the given file descriptor.
// Release locks on this file held by this process.
int Library::close(int fd){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	int res = _sysCall->Close(fd);
	if(res != 0){
		// failed to close
		return -1;
	}
	_fdTable->removeFileDescriptor(fd);
	return 0;
}

// Read num-bytes from the file that is identified by fd.
// Returns the string read, followed by a newline and then the number of bytes that were actually read.
// Remember read uses the current file pointer to know where to start reading from,
// and the operation advances the file pointer.
// The output should be shown on stdout.
string Library::read(int fd, int num_bytes){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return "";
	}

	unsigned char* buf = Utils::InitBytes(num_bytes+1);
	int amount = _sysCall->Read(fd,num_bytes,buf);

	if(amount == -1){
		// cant read error
		return "";
	}

	buf[num_bytes] = 0;
	ostringstream str;
	str << Utils::CharKohavToString((char*)buf) << endl << amount << endl;
	string res = str.str();

	delete buf;

	return res;
}

// writes the string to the file. Returns the number of bytes actually written.
// Remember write uses the current file pointer to know where to start writing from,
// and the operation advances the file pointer.
int Library::write(int fd, string string_to_write){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	unsigned char* uck = (unsigned char*)string_to_write.c_str();
	int length = string_to_write.length();
	int res = _sysCall->Write(fd, length, uck);

	return res;
}

// imports a real file from linux's file system from the given address into the file fd.
// In this way files can be imported into the system.
int Library::writeFile(int fd, string fileName){

	// open real file name
	ifstream writeFile;
	writeFile.open(fileName.c_str());
	if (!writeFile) {
        cout << "Unable to open Real file: " << fileName << endl;
        return -1; // terminate with error
    }

    char buf[64];
	ostringstream str;

	// read all the data
    while(!writeFile.eof()){
    	writeFile.getline(buf,64);
    	str << buf;
   	}
    writeFile.close();

    // making string from the data
    string text = str.str();

    // try to write it into our files...
    int res = write(fd,text);

	return res;
}

// locks file, so that only read operations are allowed.
// There is no limit on the number of processes peitted to read the file.
// No processes are allowed to write to the file while a process holds a read lock to the file.
// It is not obligatory to lock the file to read it. You should not block if it is locked, rather return an error.
int Library::lck_rd(int fd){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	int res = _sysCall->lockRead(fd);

	return res;
}

// locks file, so that only one process may hold the lock.
// This process may write to the file, and no other processes may write to it or read from it.
// A child does not inherit this lock. It is not obligatory to lock the file to write to it.
// You should not block if it is locked, rather return an error.
int Library::lck_wr(int fd){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	int res = _sysCall->lockWrite(fd);

	return res;
}

// releases the reading lock held by this process. No other process may release this lock.
int Library::rlslck_rd(int fd){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	int res = _sysCall->releaseLockRead(fd);

	return res;

}

// releases the writing lock held by this process. Only the process which locked the file may release the lock.
int Library::rlslck_wr(int fd){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	int res = _sysCall->releaseLockWrite(fd);

	return res;
}

// moves the file pointer to the given offset from start of file.
// If the pointer is set to an offset after the end of the file, this is o.k.
// /If data is later written at this point, subsequent reads of the data in the gap
// return bytes of zeros (until data is actually written into the gap).
// The size of the file should not be updated until data is written to that point.
int Library::lseek(int fd, int offset){
	int ans = _fdTable->findIndexOfFileDescriptor(fd);
	if(ans == -1){
		// no such fd in fd_table
		return -1;
	}
	int res = _sysCall->Seek(fd, offset);

	return res;

}

// deletes the file.
int Library::rm(string file_name){

	string fullPath = getFullPathName(file_name);
	char* path = (char*)fullPath.c_str();

	ostringstream s;
	s << "Library::rm - isDir on: " << path << " get " << _sysCall->isDir(path) << endl;
	Log::log(s,0,"debug");

	int res = _sysCall->RmFile(path);

	return res;
}

// deletes the directory. A directory can only be deleted if it is empty.
int Library::rmdir(string dir_name){

	string fullPath = getFullPathName(dir_name);
	char* path = (char*)fullPath.c_str();

	int res = _sysCall->RmDir(path);

	return res;
}

// recursively deletes directory, all sub-directories and all files.
// If one of the files is open, terminate and return error.
// It is o.k. if the system starts deleting files and then finds one open,
// to then return an error. This means that the command may be executed partially.
/*
int Library::rmdir_r2(string dir_name){

	ostringstream s;
	s << "Library::rmdir_r: rel_path: " << dir_name << endl;
	Log::log(s.str(),0,"debug");

	string fullPath = getFullPathName(dir_name);

	char* path = (char*)fullPath.c_str();

	bool dirBool = _sysCall->isDir(path);

	s << "Library::rmdir_r: full_Path: " << fullPath << " isDir returned: " << dirBool << endl;
	Log::log(s.str(),0,"debug");

	if(dirBool){
		vector<pair<string, int> >* vec = _sysCall->lsVector(path);
		cout << vec->size() << endl;
		if(vec->size() == 0){
			// empty Dir
			int res = rmdir(dir_name);
			if(res != 0){
				// cannot do that...
				delete vec;
				return -1;
			}
			delete vec;
			return 0;
		}
		//not Empty Dir...
		for(unsigned int i = 0; i < vec->size(); i++){
			ostringstream str;
			str << dir_name << "/";// << vec->at(i).first << endl;
			string g = str.str();
			g.append(vec->at(i).first);
			cout << "vec->at(i).first: " << vec->at(i).first << endl;
			cout << "g is: " << g << endl;
			string tmpPath = g;

			s << "Library::rmdir_r: nextcall of rmdir_r with : " << tmpPath << endl;
			Log::log(s.str(),0,"debug");
			int res = rmdir_r(tmpPath);
			if(res != 0){
				// cannot do that...
				delete vec;
				return -1;
			}
		}
		delete vec;

		//deleted all the files inside now deleting myself...
		int res = rmdir(dir_name);
		return res;
	}
	// it is a file... (soft or hard link)
	string file_name = dir_name;
	int res = rm(file_name);
	if(res != 0){
		// cannot do that...
		return -1;
	}
	return 0;

}*/

// recursively deletes directory, all sub-directories and all files.
// If one of the files is open, terminate and return error.
// It is o.k. if the system starts deleting files and then finds one open,
// to then return an error. This means that the command may be executed partially.
int Library::rmdir_r(string dir_name){

	//ostringstream s1;
	//s1 << "Library::rmdir_r: rel_path: " << dir_name << endl;
	//Log::log(s1.str(),0,"debug");

	string fullPath = getFullPathName(dir_name);

	char* path = (char*)fullPath.c_str();

	bool dirBool = _sysCall->isDir(path);

	//ostringstream s2;
	//s2 << "Library::rmdir_r: full_Path: " << fullPath << " isDir returned: " << dirBool << endl;
	//Log::log(s2.str(),0,"debug");

	if(dirBool){
		vector<pair<string, int> >* vec = _sysCall->lsVector(path);
		//cout << vec->size() << endl;
		if(vec->size() == 0){
			// empty Dir
			int res = rmdir(dir_name);
			if(res != 0){
				// cannot do that...
				delete vec;
				return -1;
			}
			ostringstream sdel1;
			sdel1 << "Library::rmdir_r - Directory Delted: " << dir_name << endl;
			Log::log(sdel1.str(),0,"debug");
			delete vec;
			return 0;
		}
		//not Empty Dir...
		for(unsigned int i = 0; i < vec->size(); i++){
			//cout << "vec->at(i).first: " << vec->at(i).first << endl;
			vector<string>* vp = Utils::tokPath(dir_name);
			vp->push_back(vec->at(i).first);

			string recPath = Utils::pathFromTokens(vp);
			//cout << "vp->size(): " << vp->size() << endl;
			string g = "";
			for(unsigned int j = 0; j<vp->size();j++ ){
				//cout << vp->at(j).length() << " - " << vp->at(j) << endl;
				g = g + vp->at(j);
				//cout << "g is: " << g << " len= " << g.length() << endl;
			}
			//ostringstream s3;
			//s3 << "Library::rmdir_r: next call of rmdir_r with : " << recPath << endl;
			//Log::log(s3.str(),0,"debug");
			int res = rmdir_r(recPath);
			if(res != 0){
				// cannot do that...
				delete vec;
				return -1;
			}
		}
		delete vec;

		//deleted all the files inside now deleting myself...
		int res = rmdir(dir_name);
		ostringstream sdel2;
		sdel2 << "Library::rmdir_r - Directory Delted: " << dir_name << endl;
		Log::log(sdel2.str(),0,"debug");
		return res;
	}
	// it is a file... (soft or hard link)
	string file_name = dir_name;
	int res = rm(file_name);
	ostringstream sdel3;
	sdel3 << "Library::rmdir_r - Dile Delted: " << file_name << endl;
	Log::log(sdel3.str(),0,"debug");
	if(res != 0){
		// cannot do that...
		return -1;
	}
	return 0;

}

// returns a list of the files in the given directory, each file in a different line
// and including the file-name and its size (in bytes). If ls is given without an argument,
// the ls of the current directory should be returned.
// Output should be as follows: each file/dir in the given directory in a separate line,
// directories have the "/" char appended to the end of their name.
string Library::ls(string dir_name){

	string fullPath = getFullPathName(dir_name);
	char* path = (char*)fullPath.c_str();

	bool check = _sysCall->isDir(path);
	if(!check){ // not a directory
		return "";
	}

	vector<pair<string, int> >* vec = _sysCall->lsVector(path);
	ostringstream str;
	for(unsigned int i = 0; i<vec->size(); i++){
		int len = vec->at(i).first.length();
		str << vec->at(i).first;
		for(int j = len; j<20; j++){
			str << " ";
		}
		//cout << "vec->at(" << i << ").second= " << vec->at(i).second << endl;
		str << vec->at(i).second << endl;
	}
	str << "Total Files & Directories: " << vec->size() << endl;

	string ans = str.str();

	delete vec;

	return ans;
}

// changes the old-file-name to new file name. This can be just changing its name
// in the same directory, or even moving the file to a different directory.
int Library::mv(string old_file_name, string new_file_name){

	string fullPathOld = getFullPathName(old_file_name);
	char* pathOld = (char*)fullPathOld.c_str();

	ostringstream s1;
	s1 << "Library::mv: old_file_name: " << pathOld << endl;
	Log::log(s1.str(),0,"debug");

	string fullPathNew = getFullPathName(new_file_name);
	char* pathNew = (char*)fullPathNew.c_str();

	ostringstream s2;
	s2 << "Library::mv: new_file_name: " << pathNew << endl;
	Log::log(s2.str(),0,"debug");

	int ans = _sysCall->moveFile(pathOld,pathNew);

	if(ans == -1){
		// moved failed
	}

	return ans;
}

// changes current working directory of the current process to new-directory.
void Library::cd(string new_directory){

	string fullPath = getFullPathName(new_directory);
	char* path = (char*)fullPath.c_str();

	bool ans = _sysCall->isDir(path);
	if(ans){
		_currPath = fullPath;
	}
	else{
		// no such directory
	}
}



int Library::getPremision(string premitions){
	if(premitions.compare("\"read-only\"") == 0){
		int ans = READ;
		return ans;
	}
	if(premitions.compare("\"write-only\"") == 0){
		int ans = WRITE;
		return ans;
	}
	if(premitions.compare("\"read-and-write\"") == 0){
		int ans = READWRITE;
		return ans;
	}
	return -1; // no such Premition
}
